package com.mustafaiev.tair.cts.dao.jpa;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.mustafaiev.tair.cts.dao.IPurchaseDAO;
import com.mustafaiev.tair.cts.exeption.DataNotRemovedException;
import com.mustafaiev.tair.cts.exeption.DataNotStoredException;
import com.mustafaiev.tair.cts.model.Purchase;

@Repository(value = "purchaseDao")
@Transactional
public class PurchaseDAO implements IPurchaseDAO {

	private static final String SELECT_ALL_FROM_PURCHASE = "from Purchase";

	private static final String DELETE_FROM_PURCHASE = "delete from Purchase where id = ?";
	private static final String SELECT_PURCHASES_FOR_BASKET = "from Purchase where basket_id = ?";

	private static final Logger LOGGER = Logger.getLogger(PurchaseDAO.class);

	private HibernateTemplate hibernateTemplate;

	@Autowired
	public void setHibernateTemplate(final HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	@Override
	public void doSave(final Purchase t) throws DataNotStoredException {
		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		final Transaction transaction = session.getTransaction();
		try {
			transaction.begin();
			session.save(t);
			transaction.commit();
		} catch (final HibernateException e) {
			LOGGER.error(e);
		} finally {
			session.close();
		}

	}

	@Override
	public void saveBatch(final List<Purchase> purchases)
			throws DataNotStoredException {
		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		final Transaction transaction = session.getTransaction();

		try {
			transaction.begin();
			for (final Purchase purchase : purchases) {
				if (purchase != null) {
					session.saveOrUpdate(purchase);
				}
			}
			transaction.commit();
		} catch (final HibernateException e) {
			LOGGER.error(e);
		} finally {
			session.close();
		}
	}

	@Override
	public void doDeleteById(final Long id) throws DataNotRemovedException {

		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		final Transaction transaction = session.getTransaction();

		try {
			transaction.begin();
			session.createQuery(DELETE_FROM_PURCHASE).setLong(0, id)
					.executeUpdate();
			transaction.commit();
		} catch (final HibernateException e) {
			LOGGER.error(e);
		} finally {
			session.close();
		}

	}

	@Override
	public void deleteBatch(final List<Purchase> purchases) {
		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		final Transaction transaction = session.getTransaction();

		try {
			transaction.begin();
			for (final Purchase purchase : purchases) {
				if (purchase != null) {
					session.createQuery(DELETE_FROM_PURCHASE)
							.setLong(0, purchase.getId()).executeUpdate();
				}
			}
			transaction.commit();
		} catch (final HibernateException e) {
			LOGGER.error(e);
		} finally {
			session.close();
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Purchase> retrievePurchases() {
		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		List<Purchase> purchases = null;
		try {
			purchases = session.createQuery(SELECT_ALL_FROM_PURCHASE).list();
		} catch (final HibernateException e) {
			LOGGER.error(e);
		}
		return purchases;
	}

	@Override
	public Purchase retrievePurchase(final Long id) {
		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		Purchase purchase = null;
		try {
			purchase = (Purchase) session.get(Purchase.class, id);
		} catch (final HibernateException e) {
			LOGGER.error(e);
		}
		return purchase;
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Purchase> retrievePurchasesForBasket(final Long basketId) {
		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		List<Purchase> purchases = null;
		try {
			purchases = session.createQuery(SELECT_PURCHASES_FOR_BASKET)
					.setLong(0, basketId).list();
		} catch (final HibernateException e) {
			LOGGER.error(e);
		}
		return purchases;
	}

	@Override
	public void doDelete(final Purchase t) throws DataNotRemovedException {

	}

	@Override
	public void doUpdate(final Purchase t) throws DataNotStoredException {
		// TODO Auto-generated method stub

	}

}
